package krt.wid.nohttp;

import android.content.Context;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebView;

import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.EncryptUtils;

import java.io.UnsupportedEncodingException;

/**
 * @author Marcus
 * @package krt.wid.nohttp
 * @description
 * @time 2018/9/4
 */
public class AESUtil {
    private static final String js = "var AES={sbox:[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171" +
            ",118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,2" +
            "53,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154" +
            ",7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83" +
            ",209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249" +
            ",2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,23" +
            "6,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,2" +
            "19,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234," +
            "101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97" +
            ",53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,23" +
            "0,66,104,65,153,45,15,176,84,187,22],Invsbox:[82,9,106,213,48,54,165,56,191,64,163,158,129,243,215,251,124,22" +
            "7,57,130,155,47,255,135,52,142,67,68,196,222,233,203,84,123,148,50,166,194,35,61,238,76,149,11,66,250,195,78,8,46" +
            ",161,102,40,217,36,178,118,91,162,73,109,139,209,37,114,248,246,100,134,104,152,22,212,164,92,204,93,101,182,146" +
            ",108,112,72,80,253,237,185,218,94,21,70,87,167,141,157,132,144,216,171,0,140,188,211,10,247,228,88,5" +
            ",184,179,69,6,208,44,30,143,202,63,15,2,193,175,189,3,1,19,138,107,58,145,17,65,79,103,220,234,151,242," +
            "207,206,240,180,230,115,150,172,116,34,231,173,53,133,226,249,55,232,28,117,223,110,71,241,26,113,29,41," +
            "197,137,111,183,98,14,170,24,190,27,252,86,62,75,198,210,121,32,154,219,192,254,120,205,90,244,31,221,168," +
            "51,136,7,199,49,177,18,16,89,39,128,236,95,96,81,127,169,25,181,74,13,45,229,122,159,147,201,156,239,160,224" +
            ",59,77,174,42,245,176,200,235,187,60,131,83,153,97,23,43,4,126,186,119,214,38,225,105,20,99,85,33,12,125]," +
            "rcon:[[0,0,0,0],[1,0,0,0],[2,0,0,0],[4,0,0,0],[8,0,0,0],[16,0,0,0],[32,0,0,0],[64,0,0,0],[128,0,0,0]," +
            "[27,0,0,0],[54,0,0,0]],cipher:function(e,b){var a=4;var g=b.length/a-1;var h=[new Array(a),new Array(a),new Array(a)" +
            ",new Array(a)];var d=new Array(4*a);var f,c;for(f=0;f<e.length;f++){h[f%4][Math.floor(f/4)]=e[f]}this.addRoundKey(h,b,0,a);for(c=1;c<g;c++){this.subBytes(h,a,0);this.shiftRows(h,a,0);this.mixColumns(h,a,0);this.addRoundKey(h,b,c,a)}this.subBytes(h,a,0);this.shiftRows(h,a,0);" +
            "this.addRoundKey(h,b,g,a);for(f=0;f<d.length;f++){d[f]=h[f%4][Math.floor(f/4)]}return d},Invcipher:function(e,b){var a=4;" +
            "var g=b.length/a-1;var h=[new Array(a),new Array(a),new Array(a),new Array(a)];var d=new Array(4*a);var f,c;" +
            "for(f=0;f<e.length;f++){h[f%4][Math.floor(f/4)]=e[f]}this.addRoundKey(h,b,g,a);for(c=g-1;c>=1;c--){this.shiftRows(h,a,1);" +
            "this.subBytes(h,a,1);this.addRoundKey(h,b,c,a);this.mixColumns(h,a,1)}this.shiftRows(h,a,1);this.subBytes(h,a,1);" +
            "this.addRoundKey(h,b,c,a);for(f=0;f<d.length;f++){d[f]=h[f%4][Math.floor(f/4)]}return d},subBytes:function(e,a,b){var d,g;var b=b||0;var f=b===0?this.sbox:this.Invsbox;for(g=0;g<a;g++){for(d=0;d<4;d++){e[d][g]=f[e[d][g]]}}},shiftRows:function(f,a,d){var b=new Array(a);var d=d||0;var e,g;d=d===0?1:-1;for(e=1;e<4;e++){for(g=0;g<a;g++){b[g]=f[e][(g+e*d+a)%a]}for(g=0;g<4;g++){f[e][g]=b[g]}}},mixColumns:function(g,a,e){var f,j,d;var b=new Array(a);var h=[[2,3,1,1],[14,11,13,9]];for(j=0;j<a;j++){for(f=0;f<4;f++){b[f]=g[f][j]}for(f=0;f<4;f++){g[f][j]=0;for(d=0;d<4;d++){g[f][j]^=this.FFmul(h[e][d],b[(f+d)%4])}}}},FFmul:function(d,c){var g=new Array(4);var f=0;var e;g[0]=c;for(e=1;e<4;e++){g[e]=g[e-1]<<1;if(g[e-1]&128){g[e]^=283}}for(e=0;e<4;e++){if((d>>e)&1){f^=g[e]}}return f},addRoundKey:function(f,b,d,a){var e,g;for(g=0;g<a;g++){for(e=0;e<4;e++){f[e][g]^=b[d*4+g][e]}}},keyExpansion:function(g){var d=g.length/4;var a=4;var h=d+6;var b=new Array(a*(h+1));var c=new Array(4);var f,e;for(f=0;f<d;f++){b[f]=[g[4*f],g[4*f+1],g[4*f+2],g[4*f+3]]}for(f=d;f<b.length;f++){b[f]=new Array(4);for(e=0;e<4;e++){c[e]=b[f-1][e]}if(f%d===0){this.rotWord(c);this.subWord(c);for(e=0;e<4;e++){c[e]^=AES.rcon[f/d][e]}}else{if(d>6&&f%d===4){this.subWord(c)}}for(e=0;e<4;e++){b[f][e]=b[f-d][e]^c[e]}}return b},rotWord:function(a){var b=a[0];var c;for(c=0;c<3;c++){a[c]=a[c+1]}a[3]=b},subWord:function(a){var b;for(b=0;b<4;b++){a[b]=this.sbox[a[b]]}}};AES.Crypto=function(b){this.String2Array=function(d,f){var e;if(f!=null){var c=new Array(16);for(e=0;e<16;e++){c[e]=d.charCodeAt(16*f+e)||0}}else{var g=d.length<=16?16:d.length<=24?24:32;var c=new Array(g);for(e=0;e<g;e++){c[e]=d.charCodeAt(e)||0}}return c};this.Byte2Char=function(d){var e;var c='';for(e=0;e<d.length/2;e++){c+=String.fromCharCode(parseInt(d[e*2],16)*16+parseInt(d[e*2+1],16))}return c};this.encrypt=function(e){var h=Math.ceil(e.length/a);var d=new Array();var g,f,j;var i,k;for(i=0;i<h;i++){g=AES.cipher(this.String2Array(e,i),this.keySchedule);j=i*a;for(k=0;k<16;k++){d[j+k]=g[k]<16?('0'+g[k].toString(16)):g[k].toString(16)}}return d.join('')};this.decrypt=function(e){var h=Math.ceil(e.length/a*0.5);var d=new Array();var g,f,j;var i,k;e=this.Byte2Char(e);for(i=0;i<h;i++){g=AES.Invcipher(this.String2Array(e,i),this.keySchedule);j=i*a;for(k=0;k<16&&g[k]!=0;k++){d[j+k]=String.fromCharCode(g[k])}}return d.join('')};var a=16;this.key=this.String2Array(b,null);this.keySchedule=AES.keyExpansion(this.key)};";

    private static WebView encode(Context context) {
        WebView webView = new WebView(context);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("javascript:" + js);
        return webView;
    }

    /**
     * 加密
     *
     * @param context
     * @param content
     * @param key
     */
    public static void encrypt(final Context context, String content, String key, final AesCallBack callBack) {
        WebView webView = encode(context);
        String base64Encode = new String(EncodeUtils.base64Encode(content));
        webView.evaluateJavascript("javascript:new AES.Crypto('" + key + "').encrypt('" + base64Encode + "')", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                callBack.callBack(value.replace("\"", ""));
            }
        });

    }


    /**
     * 解密
     */
    public static void decode(Context context, String content, String key, final AesCallBack callBack) {
        WebView webView = encode(context);
        webView.evaluateJavascript("javascript:new AES.Crypto('" + key + "').decrypt('" + content + "')", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                callBack.callBack(new String(EncodeUtils.base64Decode(value)));
            }
        });
    }

    public interface AesCallBack {
        void callBack(String content);
    }
}
